/*
 * Copyright 2009 Jamie Gennis
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.code.gwt.remoteaction.rebind;

import com.google.code.gwt.remoteaction.client.Action;
import com.google.code.gwt.remoteaction.client.RemoteAction;
import com.google.code.gwt.remoteaction.client.RemoteActionService;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.name.Named;
import java.util.ArrayList;

/**
 * A collection of remote action service interfaces used for testing.
 * 
 * @author jgennis
 */
class Services {

  public interface ServiceA extends RemoteActionService {

    @RemoteAction(ActionA.class)
    public void methodA();
  }

  public interface ServiceAAsync {

    public void methodA(AsyncCallback<Void> callback);
  }

  public interface ServiceB extends RemoteActionService {

    @RemoteAction(ActionB.class)
    public int methodB(int a);
  }

  public interface ServiceBAsync {

    public void methodB(int a, AsyncCallback<Integer> callback);
  }

  public interface ServiceC extends RemoteActionService {

    @RemoteAction(ActionA.class)
    public void methodA();

    @RemoteAction(ActionB.class)
    public int methodB(int a);

    @RemoteAction(ActionC.class)
    public Long methodC(String a, int b, Long c);
  }

  public interface ServiceCAsync {

    public void methodA(AsyncCallback<Void> callback);

    public void methodB(int a, AsyncCallback<Integer> callback);

    public void methodC(String a, int b, Long c, AsyncCallback<Long> callback);
  }

  public interface ServiceD extends RemoteActionService {

    @RemoteAction(ActionD.class)
    public void methodD(@Named("a") int a, @Named("b") int b);
  }

  public interface ServiceDAsync {

    public void methodD(int a, int b, AsyncCallback<Void> callback);
  }

  public class ActionA implements Action {
  }

  public class ActionB implements Action {

    public int aaa;

    @SuppressWarnings("unused")
	private ActionB() {
    }

    public ActionB(int aaa) {
      this.aaa = aaa;
    }
  }

  public class ActionC implements Action {

    protected String aaa;

    protected int b;

    public Long c;

    @SuppressWarnings("unused")
	private ActionC(){
    }

    public ActionC(String aaa, int b, Long c) {
      this.aaa = aaa;
      this.b = b;
      this.c = c;
    }

    public String getAaa() {
      return aaa;
    }

    public int getB() {
      return b;
    }

    public Long getC() {
      return c;
    }
  }

  public class ActionD implements Action {

    public int a;

    protected int b;

    @SuppressWarnings("unused")
	private ActionD() {
    }

    public ActionD(int a, int b) {
      this.a = a;
      this.b = b;
    }

    public int getA() {
      return a;
    }

    public int getB() {
      return b;
    }
  }

  public static class BadService_Class {
  }

  public interface BadService_ClassAsync {
  }

  public interface BadService_AsyncClass {
  }

  public static class BadService_AsyncClassAsync {
  }

  public interface BadService_NoAsync {
  }

  public interface BadService_NoAnnotation {

    public void methodA();
  }

  public interface BadService_NoAnnotationAsync {

    public void methodA(AsyncCallback<Void> callback);
  }

  public interface BadService_AsyncEmpty {

    @RemoteAction(ActionA.class)
    public void methodA();
  }

  public interface BadService_AsyncEmptyAsync {
  }

  public interface BadService_BadMethods {

    @RemoteAction(ActionA.class)
    public void methodA();

    @RemoteAction(ActionB.class)
    public int methodB(int a);

    @RemoteAction(ActionC.class)
    public Long methodC(String a, int b, Long c);

    @RemoteAction(ActionD.class)
    public void methodD(@Named("a") int a, @Named("b") int b);
  }

  public interface BadService_BadMethodsAsync {

    // 0 parameters
    public void methodA();

    // non-void return type
    public int methodA(AsyncCallback<Void> callback);

    // no matching sync method
    public void methodB(AsyncCallback<Integer> callback);

    // wrong type argument to AsyncCallback
    public void methodC(String a, int b, Long c, AsyncCallback<Boolean> callback);

    // non-AsyncCallback for the last argument
    public void methodD(int a, int b, ArrayList<Void> callback);
  }

  public class BadAction_NonPublicProperty implements Action {

    protected int a;

    public BadAction_NonPublicProperty(int a) {
      this.a = a;
    }

    protected int getA() {
      return a;
    }
  }

  public class BadAction_NonPublicConstructor implements Action {

    protected BadAction_NonPublicConstructor() {
    }
  }

  public class BadAction_NoDefaultConstructor implements Action {

    public BadAction_NoDefaultConstructor(int a) {
    }
  }
}
